package com.xframe.xdal.core.util.redis.command;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xframe.xdal.core.model.IModel;
import com.xframe.xdal.core.util.StringUtil;
import com.xframe.xdal.core.util.redis.pool.IRedisPool;
import redis.clients.jedis.commands.JedisCommands;
import redis.clients.jedis.commands.MultiKeyCommands;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description:
 * @ClassName: GetCommand
 * @Author: Lean.Liu
 * @CreateTime: 2023/4/12 10:03
 **/
public class GetCommand {

    private IRedisPool pool = null;

    public GetCommand(IRedisPool pool){
        this.pool = pool;
    }

    /**
     * 返回 key 所关联的字符串值
     * @param key   key
     * @return 当 key 为null，返回 -2, 当 key 不存在时，返回 nil ，否则，返回 key 的值。
     * key 不是字符串类型，那么返回一个错误。
     */
    public String get(String key) {
        if (StringUtil.isValueNull(key)) {
            return "-2";
        }
        JedisCommands client = pool.getClient();
        try {
            return client.get(key);
        } finally {
            pool.close(client);
        }
    }

    /**
     * 对 key 所储存的字符串值，获取指定偏移量上的位(bit)
     * @param key
     * @param offset 偏移量
     * @return  字符串值指定偏移量上的位(bit)。
     * 当 offset 比字符串值的长度大，或者 key 不存在时，返回 0
     */
    public Boolean getBit(String key, long offset) {
        if (StringUtil.isValueNull(key, offset)) {
            return false;
        }
        JedisCommands client = pool.getClient();
        try {
            return client.getbit(key,offset);
        } finally {
            pool.close(client);
        }
    }

    /**
     * 返回 key 中字符串值的子字符串，字符串的截取范围由 start 和 end
     * 两个偏移量决定(包括 start 和 end 在内)。
     * @param key
     * @param startOffset
     * @param endOffset
     * @return 截取得出的子字符串。
     */
    public String getRange(String key, long startOffset, long endOffset) {
        if (StringUtil.isValueNull(key, startOffset, endOffset)) {
            return "-2";
        }
        JedisCommands client = pool.getClient();
        try {
            return client.getrange(key,startOffset, endOffset);
        } finally {
            pool.close(client);
        }
    }

    /**
     * 将给定 key 的值设为 value
     * @param key
     * @param value
     * @return 返回给定 key 的旧值。当 key 没有旧值时，也即是， key 不存在时，返回 nil
     */
    public String getSet(String key, String value) {
        if (StringUtil.isValueNull(key, value)) {
            return "-2";
        }
        JedisCommands client = pool.getClient();
        try {
            return client.getSet(key,value);
        } finally {
            pool.close(client);
        }
    }

    /**
     * 返回list对象
     * @param key
     * @param dataType  对象类型
     * @return   返回list对象
     * @param <T>
     */
    public <T extends IModel> List<T> getCollection(String key, Class dataType) {
        if (StringUtil.isValueNull(key)) {
            return null;
        }
        JedisCommands client = pool.getClient();
        try {
            List<T> list = new ArrayList<>();
            Map mapTypes = JSON.parseObject(get(key));
            for (Object map : mapTypes.keySet()){
                JSONObject jsonObject = JSONObject.parseObject((String) mapTypes.get(map));
                T model = (T) JSON.toJavaObject(jsonObject, dataType);
                list.add(model);
            }
            return list;
        } finally {
            pool.close(client);
        }
    }

    /**
     * 返回对象
     * @param key
     * @param dataType 对象类型
     * @return  返回list对象
     * @param <T>
     */
    public <T> T getObject(String key, Class dataType){
        if (StringUtil.isValueNull(key)) {
            return null;
        }
        JedisCommands client = pool.getClient();
        try {
            String val = get(key);
            if (StringUtil.isValueNull(val)) {
                return null;
            }
            T model = (T) JSONUtil.toBean(val, dataType);
            return model;

        }catch (Exception e){
            return null;
        }finally {
            pool.close(client);
        }
    }


    public List<String> mget(String... keys){
        if (StringUtil.isValueNull(keys)) {
            return null;
        }
        MultiKeyCommands client = pool.getMultiKeyCommands();
        try {
            return client.mget(keys);
        } finally {
            pool.close(client);
        }
    }
    public List<String> mget(List<String> keys){
           return this.mget(keys.toArray(new String[keys.size()]));
    }

}
